package com.easy.generator;

import com.easy.generator.java.*;
import com.easy.generator.vue.Packagfe_Lock_Generator;
import com.easy.generator.vue.Vue_Generator;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;

/**
 * @author easy
 * @date 2025年07月05日 09:01
 */
public class Easy {


    public static String ARTIFACT_ID = "easyc";
    public static final String GROUP_ID = "com.easy";
    public static final String PROJECR_NAME = "易视界数据管理系统";
    public static final String VUE_WORKSPACE_PATH = "D:/workspace/";
    public static final String VERSION = "1.0.1";
    public static final String SERVER_PORT = "8080";
    public static final String VUE_PROJECT_NAME = ARTIFACT_ID + "vue";

    public static final String VUE_LOCAL_PATH = VUE_WORKSPACE_PATH + ARTIFACT_ID + "vue";
    /*上传文件配置*/
    public static final String FILE_URL_PREFIX = "/file";
    public static final String FILE_STATIC_PATH = "D:/upload/";

    /*登录配置*/
    public static final String LOGIN_ENTITY = "Admin";
    public static final String LOGIN_NAME_FIELD = "phone";
    public static final String LOGIN_PASSWORD_FIELD = "password";

    public static final String MYSQL_DATABASE_NAME = "stl";
    public static final String MYSQL_DRIVER = "com.mysql.cj.jdbc.Driver";
    public static final String MYSQL_URL = "jdbc:mysql://localhost:3306/" + MYSQL_DATABASE_NAME;
    public static final String MYSQL_USER = "root";
    public static final String MYSQL_PASSWORD = "123123";

    public static final String PROJECT_NAME = ARTIFACT_ID;
    //主包
    public static final String BASE_PACKAGE = GROUP_ID;

    //模块包--如果模块名称和模块包名称不一致，请修改此处
    public static final String MODEL_PACKAGE = BASE_PACKAGE + "";
    //实体类包
    public static final String BEAN_PACKAGE = MODEL_PACKAGE + ".bean";
    //Controller包
    public static final String CONTROLLER_PACKAGE = MODEL_PACKAGE + ".controller";
    public static final String SERVICE_PACKAGE = MODEL_PACKAGE + ".service";
    public static final String SERVICE_IMPL_PACKAGE = SERVICE_PACKAGE + ".impl";
    public static final String MAPPER_PACKAGE = MODEL_PACKAGE + ".mapper";
    public static final String UTIL_PACKAGE = MODEL_PACKAGE + ".util";
    public static final String CONFIG_PACKAGE = MODEL_PACKAGE + ".config";
    public static final String EXCEPTION_PACKAGE = MODEL_PACKAGE + ".exception";
    public static final String SERVICE_EXCEPTION_NAME = "ServiceException";

    //项目绝对路径
    public static String PROJECT_ABSOLUTE_URL = "";

    public static final String SRC_DIR = "/src/main/java/";
    public static final String RESOURCE_DIR = "/src/main/resources/";
    private static final int BASE = 0;
    private static final int CONTROLLER = 1;
    private static final int PASSWORD = 2;
    private static final int SERVICE = 3;
    private static final int MAPPER = 4;
    private static final int RESULT = 5;
    private static final int FILE_LOCAL = 6;
    private static final int CAPTCHA = 7;
    private static final int TOKEN = 8;
    private static final int APPLICATION = 9;
    private static final int UTIL = 10;
    private static final int POM = 11;
    private static final int YML = 12;
    private static final int TABLE_TO_BEAN = 13;
    private static final int EXCEPTION = 14;
    private static final int VUE = 15;

    public static final int[] PACKAGE_LIST = new int[]{
//            POM,
//            TABLE_TO_BEAN,//表转成实体类******必须先单独运行一遍

//            APPLICATION,     //启动类
//            YML,
//            UTIL,               //工具类
            CONTROLLER,
//            RESULT,EXCEPTION,         //控制器和结果返回类
//            SERVICE,        //业务类
//            MAPPER,         //数据访问类

//            FILE_LOCAL,     //文件本地上传处理类

//            PASSWORD,       //密码工具类
//            TOKEN,         //token工具类
//            CAPTCHA,        //验证码工具类

            VUE,

            BASE            //格式约束-----不用注释
    };


    public static void main(String[] args) throws Exception {
        init();
        if (contains(TABLE_TO_BEAN))
            TableToBeanGenerator.generate();
        //生成控制器Controller
        if (contains(CONTROLLER))
            ControllerGenerator.generate();
        //Result类生成器
        if (contains(RESULT))
            ResultGenerator.generate();
        if (contains(MAPPER))
            MapperGenerator.generate();
        if (contains(SERVICE))
            ServiceGenerator.generate();
        if (contains(FILE_LOCAL))
            FileGenerator.generate();
        if (contains(PASSWORD))
            PasswordGenerator.generate();
        if (contains(CAPTCHA))
            InnerCaptchaGenerator.generate();
        if (contains(TOKEN))
            TokenGenerator.generate();
        if (contains(APPLICATION))
            ApplicationGenerator.generate();
        if (contains(UTIL))
            UtilGenerator.generate();
        if (contains(POM))
            POMGenerator.generate();
        if (contains(YML))
            YMLGenerator.generate();
        if (contains(EXCEPTION))
            ExceptionGenerator.generate();
        if (contains(VUE))
            Vue_Generator.generate();
        System.out.println("已经生成完毕,请先更新MAVEN");
    }

    private static boolean contains(int target) {
        for (int item : PACKAGE_LIST) {
            if (item == target) {
                return true;
            }
        }
        return false;
    }

    private static void init() {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        String path = classLoader.getResource("").getPath();
        int index = path.lastIndexOf("/target");
        PROJECT_ABSOLUTE_URL = path.substring(0, index);
        int index2 = PROJECT_ABSOLUTE_URL.lastIndexOf("/") + 1;
        ARTIFACT_ID = PROJECT_ABSOLUTE_URL.substring(index2);
        System.out.println("项目绝对路径：" + PROJECT_ABSOLUTE_URL);
        System.out.println("项目名：" + Easy.ARTIFACT_ID);
    }

    public static void initPackage(String pageName) {
        String controllerPackagePath = Easy.PROJECT_ABSOLUTE_URL + Easy.SRC_DIR + Easy.convertPackagePath(pageName) + "/";
        File controllerPackage = new File(controllerPackagePath);
        if (!controllerPackage.exists()) {
            controllerPackage.mkdirs();
        }
    }

    public static void mkdirs(String dir) {

        File mk = new File(dir);
        if (!mk.exists()) {
            mk.mkdirs();
        }
    }

    public static Set<Class<?>> scanClasses(String packageName, ClassLoader classLoader) throws Exception {
        Set<Class<?>> classes = new HashSet<>();
        String path = packageName.replace('.', '/');
        Enumeration<URL> resources = classLoader.getResources(path);

        while (resources.hasMoreElements()) {
            URL resource = resources.nextElement();
            if (resource.getProtocol().equals("file")) {
                classes.addAll(findClasses(new File(resource.getFile()), packageName));
            }
        }
        return classes;
    }

    public static boolean isEntityClass(Class<?> clazz) {
        // 简单的实体类判断逻辑，可根据实际需求扩展
        return !clazz.isInterface() && !Modifier.isAbstract(clazz.getModifiers());
    }


    private static Set<Class<?>> findClasses(File directory, String packageName) throws ClassNotFoundException {
        Set<Class<?>> classes = new HashSet<>();
        if (!directory.exists()) return classes;

        File[] files = directory.listFiles();
        for (File file : files) {
            if (file.isDirectory()) {
                classes.addAll(findClasses(file, packageName + "." + file.getName()));
            } else if (file.getName().endsWith(".class")) {
                String className = packageName + '.' + file.getName().substring(0, file.getName().length() - 6);
                classes.add(Class.forName(className));
            }
        }
        return classes;
    }


    public static void copyDri(String sourceDirStr, String targetDirStr) {
        Path sourceDir = Paths.get(sourceDirStr);
        Path targetDir = Paths.get(targetDirStr);
        try {
            Files.walk(sourceDir)
                    .forEach(source -> {
                        try {
                            Path dest = targetDir.resolve(sourceDir.relativize(source));
                            if (Files.isDirectory(source)) {
                                Files.createDirectories(dest);
                            } else {
                                Files.copy(source, dest, StandardCopyOption.REPLACE_EXISTING);
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String convertPackagePath(String packageName) {
        return packageName.replace(".", "/");
    }
}
